﻿using K9Nano.Application.Dtos;
using K9Nano.Dependency;
using K9Nano.Domain.Organization;
using K9Nano.Mapping;

namespace K9Nano.Application.Organization;

public class OrganizationUnitAppService(IOrganizationUnitManager manager) : IOrganizationUnitAppService, IScopedDependency
{
    public virtual async Task<OrganizationUnitDto> CreateAsync(OrganizationUnitCreateDto input, CancellationToken cancellation)
    {
        var ou = MappingHelper.Mapper.Map<OrganizationUnit>(input);
        await manager.CreateAsync(ou, cancellation);
        var dto = MappingHelper.Mapper.Map<OrganizationUnitDto>(ou);
        return dto;
    }

    public virtual async Task<OrganizationUnitDto> UpdateAsync(OrganizationUnitEditDto input, CancellationToken cancellation)
    {
        var ou = MappingHelper.Mapper.Map<OrganizationUnit>(input);
        await manager.UpdateAsync(ou, cancellation);
        var dto = MappingHelper.Mapper.Map<OrganizationUnitDto>(ou);
        return dto;
    }

    public virtual async Task DeleteAsync(long id, CancellationToken cancellation)
    {
        await manager.DeleteAsync(id, cancellation);
    }

    public virtual async Task<IReadOnlyList<OrganizationUnitDto>> GetChildrenAsync(long? parentId, bool recursive, CancellationToken cancellation)
    {
        var children = await manager.FindChildrenAsync(parentId, recursive, cancellation);
        if (children.Count == 0)
        {
            return [];
        }

        return MappingHelper.Mapper.Map<List<OrganizationUnitDto>>(children);
    }

    public virtual async Task<OrganizationUnitDto?> GetAsync(long id, CancellationToken cancellation)
    {
        var ou = await manager.GetAsync(id, cancellation);

        if (ou == null) return null;

        var dto = MappingHelper.Mapper.Map<OrganizationUnitDto>(ou);

        return dto;
    }

    public virtual async Task<PagedResultDto<OrganizationUnitDto>> QueryAsync(OrganizationUnitQueryDto dto, CancellationToken cancellation)
    {
        var (total, items) = await manager.QueryAsync(dto.Name, dto.ParentId, dto.PageIndex, dto.PageSize, cancellation);
        if (total <= 0) return new PagedResultDto<OrganizationUnitDto>();
        var dtoItems = MappingHelper.Mapper.Map<OrganizationUnitDto[]>(items);
        return new PagedResultDto<OrganizationUnitDto>(total, dtoItems);
    }
}
